<template>
    <v-text-field
        ref="textField"
        class="key-input"
        :model-value="shortcutString"
        :label="label"
        @input="onInput"
        @keydown="onKeydown"
        hide-details="auto"
    >
        <template #append-inner>
            <!-- 确认按钮 -->
            <v-fade-transition>
                <span
                    v-if="!Shortcut.isStateEqual(shortcut, modelValue)"
                    class="ml-2)"
                    style="cursor: pointer"
                    @click="emits('update:modelValue', shortcut)"
                >
                    <v-icon>mdi-check</v-icon>
                    <v-tooltip activator="parent" location="bottom">确认</v-tooltip>
                </span>
            </v-fade-transition>

            <!-- 撤回按钮 -->
            <v-fade-transition>
                <span
                    v-if="!Shortcut.isStateEqual(shortcut, modelValue) && Shortcut.isAvailableState(modelValue)"
                    class="ml-2"
                    style="cursor: pointer"
                    @click="shortcut = modelValue"
                >
                    <v-icon>mdi-undo-variant</v-icon>
                    <v-tooltip activator="parent" location="bottom">撤回</v-tooltip>
                </span>
            </v-fade-transition>

            <!-- 清空按钮 -->
            <v-fade-transition>
                <span
                    v-if="Shortcut.isAvailableState(shortcut)"
                    class="ml-2"
                    style="cursor: pointer"
                    @click="shortcut = Shortcut.state()"
                >
                    <v-icon>mdi-close</v-icon>
                    <v-tooltip activator="parent" location="bottom">清空</v-tooltip>
                </span>
            </v-fade-transition>
        </template>
    </v-text-field>
</template>

<script setup lang="ts">
import { type PropType, ref, watch } from "vue";
import { type ShortcutState, Shortcut } from "@/lib/keyboard";
import { computed } from "vue";

const props = defineProps({
    modelValue: {
        type: Object as PropType<ShortcutState>,
        default: () => Shortcut.state(),
    },
    label: {
        type: String,
        default: "按键输入",
    },
    keyCode: {
        type: Boolean,
        default: false,
    },
    immediate: {
        type: Boolean,
        default: false,
    },
});

const emits = defineEmits<{ (event: "update:modelValue", value: ShortcutState): void }>();

// Text Field
const textField = ref<HTMLInputElement>();

// 用于存储当前的按键输入
const shortcut = ref(props.modelValue);

// 输入框内容
const shortcutString = computed(() => Shortcut.stateToString(shortcut.value, props.keyCode));

// 当 modelValue 发生变化时，将 shortcut 同步到 modelValue 中
watch(props.modelValue, (value) => {
    shortcut.value = value;
});

/**
 * 避免输入法导致输入框内容不正确
 * @param event 输入事件
 */
function onInput(event: InputEvent) {
    if (event.data !== shortcutString.value) {
        textField.value!.value = shortcutString.value;
    }
}

/**
 * 当键盘按下事件触发时执行的函数
 * @param event 键盘事件对象
 */
function onKeydown(event: KeyboardEvent) {
    event.preventDefault();
    shortcut.value = Shortcut.stateFromEvent(event);
    if (props.immediate) {
        emits("update:modelValue", shortcut.value);
    }
}
</script>
